from django import db
from django.shortcuts import render
import os.path
import urllib
import json
import jiagu
import logging
import time

# 导入uuid类
import uuid
# 导入哈希库
import hashlib
from django.db.models import Q, F, Avg
from django.http import JsonResponse
from .myner import named_entity
from .models import History, Score, User
import pickle
import openpyxl
# 导入Setting
from django.conf import settings
import unittest


# Create your views here.


def search_text(request):
    """对用户的输入进行处理，data接收前端传入的数据"""
    data = json.loads(request.body.decode('utf-8'))
    try:
        obj_hist = History(text=data['text'], Ner=data['text'] + "123", Re=data['text'] + "456")
        obj_hist.save()
        return JsonResponse({'code': 1, 'text1': data['text'] + "123", 'text2': data['text'] + "456"})

    except Exception as e:
        return JsonResponse({'code': 0, 'msg': "查询异常，后端错误,具体错误：" + str(e)})


def get_history(request):
    data = json.loads(request.body.decode('utf-8'))
    try:
        # get只能取一个数据 利用 filter可以提取多条，filter限制提取谁，values表示提取的值
        obj_hists = History.objects.filter(username=data['username']).values('text', 'add_time', 'username','Ner','Re')
        hists = list(obj_hists)
        return JsonResponse({'code': 1, 'data': hists})
    except Exception as e:
        return JsonResponse({'code': 0, 'msg ': "获取历史记录失败" + str(e)})



# 先查找是否有相同的句子，在进入模型
def search_text_1(request):
    time.sleep(3)
    """对用户的输入进行处理，data接收前端传入的数据"""
    text1 = '';

    data = json.loads(request.body.decode('utf-8'))
    #obj_data = History.objects.get(text=data['text'],username = data['username'])
    try:
      #  if obj_data is not None:
           # return JsonResponse({'code': 1, 'text': obj_data.Ner, 'text2': obj_data.Re, 'id': obj_data.id})
     #   else:
        with open(r'D:\Github\django\my_vue_Be\apps\search\argument.pickle', 'rb') as f:
            word_2_index = pickle.load(f)
            model = pickle.load(f)
            index_2_tag = pickle.load(f)
            device = pickle.load(f)
            """此处放对传入的text进行处理"""
            "分词操作"
            text = named_entity(word_2_index, model, index_2_tag, device, str(data['text']))
            sentences = named_entity(word_2_index, model, index_2_tag, device, str(data['text']))

        "提取关系"
        text2 = jiagu.knowledge(data['text'])
        kol = list(text2)

        if sentences is not None:
            i = 0;

            while sentences[i]!=']':
                if sentences[i]=='_':
                    if sentences[i+1] == 'B':
                        text1  +=  '[' + sentences[i - 1]
                    elif sentences[i+1] == 'M':
                        text1 += sentences[i - 1];
                    elif sentences[i + 1] == 'E':
                        text1 += sentences[i - 1]+']';
                    i = i+1
                else:
                    i = i+1
            print(text1 + "&&&&&&")
            if kol is not None:
                obj_hist = History(username = data['username'],Ner=str(text1), Re=str(kol), text=data['text'])

                obj_hist.save()

                obj_hist1 = History.objects.get(username = data['username'], text=data['text'])
                id_ = obj_hist1.id

                obj_hists = History.objects.all().values()

                hists = list(obj_hists)

                return JsonResponse({'code': 1, 'text': text1, 'text2': kol, 'test3': hists, 'id': id_})

            else:

                return JsonResponse({'code': 0, 'msg': "查询异常，数据2为空"})
        else:

            return JsonResponse({'code': 0, 'msg': "查询异常，数据1为空"})

    except Exception as e:
        return JsonResponse({'code': 0, 'msg': "查询异常，后端错误,具体错误：" + str(e)})


# 将用户输入的txt文件分句存储
def get_sentences(request):
    import chardet

    data = json.loads(request.body.decode('utf-8'))

    #传来的是文件名，并且是在数据库可以提取到的
    film_name = './static'+ data['txt_name']
    try:
        with open(film_name, 'rb') as file:
            file_data = file.read()
            encoding = chardet.detect(file_data)['encoding']

        with open(film_name, encoding=encoding) as file:  # 这个地方需要修改，因为文件时从数据库中读取出来的
            text = file.read()
            sentences = text.split('.')
            # 使用split()方法按句号断开文本，将每个句子存储到一个数组中

            sentence_array = []
            for sentence in sentences:
                sentence_array.append(sentence.strip())
            # 遍历每个句子，并将其添加到一个数组中，使用strip()方法去掉句子前后的空格

        print(sentence_array)
        sentence_array = list(sentence_array)
        return JsonResponse({'code': 1, 'sentences': sentence_array})

    except Exception as e:
        return JsonResponse({'code': 0, 'msg': "查询异常，后端错误,具体错误：" + str(e)})

from django.core.files.storage import FileSystemStorage
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Allfile

@csrf_exempt


def upload(request):
    data = json.loads(request.body.decode('utf-8'))
    try:
        newName = get_random_str()+ str(data['filename'])
        with open('.\\static\\'  +newName, 'wb') as f:
            f.write(data['file'].encode('utf-8'))
        obj_file = Allfile(
            file_path='.\\static\\' + newName,
            file_name=newName,
            file_size=data['filesize'],
            file_type=data['filetype']
        )
        obj_file.save()
        obj_files = Allfile.objects.all().values()
        files = list(obj_files)

        return JsonResponse({'code': 1, 'files': newName})
    except Exception as e:
        return JsonResponse({'code': 0, 'message': str(e)})


# 获取随机字符
def get_random_str():
    # 获取uuid的随机数
    uuid_val = uuid.uuid4()
    # 获取uuid的随机数字符串
    uuid_str = str(uuid_val).encode('utf-8')
    # 获取md5实例
    md5 = hashlib.md5()
    # 拿取uuid的md5摘要
    md5.update(uuid_str)
    # 返回固定长度的字符串
    return md5.hexdigest()


def Edit_Ner(request):
    data = json.loads(request.body.decode('utf-8'))
    try:
        obj_hist = History.objects.get(id=data['id'])
        obj_hist.Ner = data['text']
        obj_hist.save()
        obj_hists = History.objects.all().values()
        hists = list(obj_hists)
        return JsonResponse({'code':1,'hists':hists})
    except Exception as e:
        return JsonResponse({'code':0,'msg':str(e)})


def Edit_Re(request):
    data = json.loads(request.body.decode('utf-8'))
    try:
        obj_hist = History.objects.get(id=data['id'])
        obj_hist.Re = data['text']
        obj_hist.save()
        obj_hists = History.objects.all().values()
        hists = list(obj_hists)
        return JsonResponse({'code':1,'hists':hists})
    except Exception as e:
        return JsonResponse({'code':0,'msg':str(e)})

# 删除数据单条
def delete_search(request):
    data = json.loads(request.body.decode("utf-8"))
    try:
        obj_search = History.objects.get(text=data['text'],username=data['username'])
        obj_search.delete()
        obj_hists = History.objects.all().values()
        hists = list(obj_hists)
        return JsonResponse({'code': 1, 'data': hists})
    except Exception as e:
        return JsonResponse({"code": 0, "msg": "删除失败！！" + str(e)})


# 删除多条
def delete_searches(request):
    data = json.loads(request.body.decode("utf-8"))
    try:
        # 遍历传递的集合
        for one_search in data['Historys']:
            obj_search = History.objects.get(text=one_search['text'], username=one_search['username'])

            # 删除
            obj_search.delete()
        obj_hists = History.objects.all().values()
        hists = list(obj_hists)
        return JsonResponse({'code': 1, 'data': hists})
    except Exception as e:
        return JsonResponse({"code": 0, "msg": "批量删除失败！！" + str(e)})

# 存储对应分数
def get_score(request):
    data = json.loads(request.body.decode('utf-8'))
    try:
        obj_hist = History.objects.get(id=data['id'])
        obj_hist.Score = data['score']
        obj_hist.save()
        obj_hists = History.objects.all().values()
        hists = list(obj_hists)
        count_score()
        return JsonResponse({"code": 1, "hists": hists})
    except Exception as e:
        return JsonResponse({"code": 0, "msg": "分数存储失败" + str(e)})

# 求同一句话不同用户的综合评分
def count_score():
    scores = History.objects.values('text').annotate(avg_score=Avg('Score'))

    # 插入 Score 表
    for score in scores:
        text, avg_score = score['text'], score['avg_score']
        Score.objects.create(text=text, score=avg_score)




def check_username(request):
    """检查并接收输入的用户名"""
    # data接收数据
    data = json.loads(request.body.decode('utf-8'))
    # 查找数据库中是否有对应的用户名
    obj_users = User.objects.filter(username=data['username'])
    # 进行校验
    try:
        if obj_users.count() == 0:  # 表示不存在这样的用户名
            return JsonResponse({'code': 1, 'exists': False, 'msg': '用户名不存在'})
        else:  # 表示存在
            return JsonResponse({'code': 1, 'exists': True})

    except Exception as e:
        return JsonResponse({'code': 0, "msg": "校验用户名失败，具体原因：" + str(e)})



def check_password(request):
    """密码是否正确"""
    data = json.loads(request.body.decode('utf-8'))
    try:
        # 查找该用户名
        obj_users = User.objects.filter(username=data['username'])  # data中 的值的变量应该与前端定义的变量名相同
        # 如果用户名存在
        if obj_users.count() != 0:
            # 当前端输入的密码（data['password']）与后端数据库中的password相同时
            object_user = User.objects.filter(password=data['password'], username=data['username'])
            # 存在密码相同
            if object_user.count() != 0:
                return JsonResponse({'code': 1, 'exists': True, })  # 只要code为1则用户存在，
            else:  # 不存在密码相同
                return JsonResponse({'code': 1, 'exists': False,'msg':'密码错误' })  # 密码错误
        else:  # 用户名不存在
            return JsonResponse({'code': 2, 'exists': False,'msg':'用户不存在'})  # 用户不存在
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': '登录出现异常，具体错误如下：' + str(e)})


#查询数据
def query_text(request):
    data = json.loads(request.body.decode('utf-8'))
    try:
        object_hists = History.objects.filter(username=data['username']).values()
        object_hist = object_hists.filter(Q(text__icontains=data['inputStr'])).values()
        hist = list(object_hist)
        hists = list(object_hists)
        if object_hist.count() != 0:
            return JsonResponse({'code': 1, "data": hist})
        else:
            return JsonResponse({'code': 0, "msg": "不存在该记录"})
    except Exception as e:
        return JsonResponse({'code':'0','msg':'數據查詢異常'})



# 导出
import os
import pandas as pd

def export_search_excel(request):
    data = json.loads(request.body.decode("utf-8"))
    """导出数据到excel"""
    try:
        for one_search in data['Historys']:
            obj_searches = History.objects.filter(text=one_search['text'], username=one_search['username']).values()
        searches = list(obj_searches)

        # 生成Excel数据
        data = pd.DataFrame(searches)
        # 准备名称
        excel_name = get_random_str() + ".xlsx"
        # 准备写入的路径
        media_root = settings.MEDIA_ROOT
        if not os.path.exists(media_root):
            os.makedirs(media_root)
        path = os.path.join(media_root, excel_name)
        if os.path.exists(path):
            print('Excel文件已成功保存到媒体文件目录下！'+str(path))
        else:
            print('Excel文件保存失败！'+str(path))
        # 写入excel
        try:
            data.to_excel(path, index=False)
            print(f'Successfully saved the Excel file at {path}')
        except Exception as e:
            print(f'Failed to save the Excel file. Error message: {e}')
        # 返回
        return JsonResponse({'code': 1, 'name': excel_name})
    except Exception as err:
        return JsonResponse({'code': 0, 'msg': str(err)})

def write_to_excel(data: list, path: str):
    """把数据库写入到Excel"""
    # 实例化一个workbook
    workbook = openpyxl.Workbook()
    # 激活一个sheet
    sheet = workbook.active
    # 为sheet命名
    sheet.title = 'search_hist'
    # 准备keys
    keys = data[0].keys()
    # 准备写入数据
    for index, item in enumerate(data):
        # 遍历每一个元素
        for k, v in enumerate(keys):
            sheet.cell(row=index + 1, column=k + 1, value=str(item[v]))

    if os.path.exists(path):
        print('成功保存到媒体文件目录下！')
    else:
        print('保存失败！')
    # 写入到文件
    workbook.save(path)
    if os.path.exists(path):
        print('成功保存到媒体文件目录下！')
    else:
        print('保存失败！')



